using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using OpenComposite.EII.Repository;
using System.Diagnostics;

namespace OpenComposite.EII.RepositoryUIs
{
	[ToolboxItem(false)]
	public partial class UCRepositoryItemList : UserControl
	{
		#region Initialization
		public UCRepositoryItemList()
		{
			_serviceProvider = null;
			imageList = Helpers.GetRepositoryItemTypeImageList();

			InitializeComponent();
			init();
		}
		public UCRepositoryItemList(IServiceProvider serviceProvider)
		{
			_serviceProvider = serviceProvider;
			imageList = Helpers.GetRepositoryItemTypeImageList();

			InitializeComponent();

			init();
		}
		private void init()
		{
			dgridObjectList.AutoGenerateColumns = false;
			if ( _serviceProvider != null ) {
				Services.IRepositoryChangeService changeService =
					_serviceProvider.GetService(typeof(Services.IRepositoryChangeService))
						as Services.IRepositoryChangeService;
				if ( changeService != null ) {
					changeService.RepositoryChanged += new OpenComposite.EII.Services.RepositoryChangedEventHandler(changeService_RepositoryChanged);
					changeService.RepositoryAdded += new OpenComposite.EII.Services.RepositoryEventHandler(changeService_RepositoryAdded);
					changeService.RepositoryRemoved += new OpenComposite.EII.Services.RepositoryEventHandler(changeService_RepositoryRemoved);
				}
			}
		}

		#endregion

		#region Public Members

		#region Properties
		public int FolderID
		{
			get { return _folderId; }
			set
			{
				if ( _folderId != value ) {
					_folderId = value;
					doFolderIDChanged();
				}
			}
		}
		public IServiceProvider ServiceProvider
		{
			get { return _serviceProvider; }
			set { _serviceProvider = value; }
		}
		public bool CustomValueVisible
		{
			get { return colCustomValue.Visible; }
			set { colCustomValue.Visible = value; }
		}
		public string CustomValueProperty
		{
			get { return colCustomValue.DataPropertyName; }
			set { colCustomValue.DataPropertyName = value; }
		}
		public string CustomValueColumnHeader
		{
			get { return colCustomValue.HeaderText; }
			set { colCustomValue.HeaderText = value; }
		}
		#endregion

		#region Methods
		public void SetParentRepositoryItem(ItemType type, int id)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			_parentItem = repSvc.GetItem(type, id, true);
			fillObjectList();
		}
		#endregion

		#endregion

		#region Protected Members

		#region Methods
		protected override object GetService(Type service)
		{
			if ( _serviceProvider != null )
				return _serviceProvider.GetService(service);
			else
				return base.GetService(service);
		}
		#endregion

		#endregion

		#region Private Members

		#region Variables
		private int _folderId = -1;
		private IRepositoryItem _parentItem = null;
		private IServiceProvider _serviceProvider;
		private List<ItemType> _childTypes = new List<ItemType>();
		private ImageList imageList;
		#endregion

		#region Methods
		private void doFolderIDChanged()
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			_parentItem = repSvc.GetItem(ItemType.GenericFolder, _folderId, true);
			fillObjectList();
		}
		private void fillObjectList()
		{
			dgridObjectList.SuspendLayout();
			try {
				if ( _parentItem != null ) {
					_childTypes.Clear();
					_childTypes.AddRange(_parentItem.AllowedChildTypes);
					DataTable dt = Global.Data.GetRepositoryHierarchyChildRepositoryList(_parentItem);
					dgridObjectList.DataSource = dt;
				} else {
					_childTypes.Clear();
					dgridObjectList.DataSource = null;
				}
				dgridObjectList.ClearSelection();
			} finally {
				dgridObjectList.ResumeLayout(true);
			}
		}
		#endregion

		#region Event Handlers
		private void tsbtnRefresh_Click(object sender, EventArgs e)
		{
			fillObjectList();
		}

		private void dgridObjectList_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
		{
			// only custom paint at first column
			if ( e.RowIndex >= 0 && e.ColumnIndex == 0 && e.Value is int &&
				 Enum.IsDefined(typeof(ItemType), (int)e.Value) ) {
				// get RepositoryService
				RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
				if ( repSvc == null ) {
					if ( !this.DesignMode )
						Debug.Fail("RepositoryService not available.");
					return;
				}
				// paint cell
				ItemType type = (ItemType)e.Value;
				bool selected = ( ( e.State & DataGridViewElementStates.Selected ) > 0 );
				e.PaintBackground(e.CellBounds, selected);
				string key = "";
				if ( selected )
					key = repSvc.GetSelectedImageKey(type);
				else
					key = repSvc.GetImageKey(type);
				if ( key != "" ) {
					Rectangle r = e.CellBounds;
					r.Inflate(-1, -1);
					Image img = imageList.Images[key];
					if ( img != null )
						e.Graphics.DrawImageUnscaled(img, r.X, r.Y, 18, 18);
				}
				e.Handled = true;
			} else {
				e.Handled = false;
			}
		}


		private void dgridObjectList_DataError(object sender, DataGridViewDataErrorEventArgs e)
		{
			if ( e.ColumnIndex == 0 ) {
				e.Cancel = true;
				e.ThrowException = false;
			}
		}

		private void changeService_RepositoryRemoved(object sender, OpenComposite.EII.Services.RepositoryEventArgs e)
		{
			//if ( e.RepositoryItem != null && _childTypes.Contains(e.RepositoryItem.RepositoryItemType) &&
			//     this.Visible && !this.IsDisposed ) {
			//    this.fillObjectList();
			//}
		}

		private void changeService_RepositoryAdded(object sender, OpenComposite.EII.Services.RepositoryEventArgs e)
		{
			//if ( e.RepositoryItem != null && _childTypes.Contains(e.RepositoryItem.RepositoryItemType) &&
			//     this.Visible && !this.IsDisposed ) {
			//    this.fillObjectList();
			//}
		}

		private void changeService_RepositoryChanged(object sender, OpenComposite.EII.Services.RepositoryChangedEventArgs e)
		{
			if ( e.RepositoryItem != null && _childTypes.Contains(e.RepositoryItem.RepositoryItemType) &&
				 !this.IsDisposed ) {
				this.fillObjectList();
			}
		}
		#endregion

		private void dgridObjectList_VisibleChanged(object sender, EventArgs e)
		{
			if ( this.Visible ) {
				fillObjectList();
			}
		}

		#endregion

		private void dgridObjectList_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
		{
			if ( e.RowIndex > -1 ) {
				DataRowView selected = dgridObjectList.SelectedRows[0].DataBoundItem as DataRowView;
				IRepositoryItem item = Global.Data.RepositoryService.GetItem((ItemType)selected["type"], (int)selected["id"], false);
				if ( !Helpers.OpenDiagram(item, _serviceProvider) ) {
					Helpers.ShowDetails(item, _serviceProvider);
				}
			}
		}

		private void dgridObjectList_KeyUp(object sender, KeyEventArgs e)
		{
			if ( e.Alt && e.Control && e.KeyCode == Keys.I ) {
				if ( dgridObjectList.SelectedRows.Count < 1 ) return;
				DataRowView drv = dgridObjectList.SelectedRows[0].DataBoundItem as DataRowView;
				RepositoryItemBase item = Global.Data.RepositoryService.GetItem((ItemType)drv["type"], (int)drv["id"], false) as RepositoryItemBase;
				Helpers.OpenDebugViewer(item, this);
				e.Handled = true;
			}
		}

		private void viewDetailToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if ( dgridObjectList.SelectedRows.Count < 1 ) return;
			DataRowView drv = dgridObjectList.SelectedRows[0].DataBoundItem as DataRowView;
			IRepositoryItem item = Global.Data.RepositoryService.GetItem((ItemType)drv["type"], (int)drv["id"], false);
			Helpers.ShowDetails(item, _serviceProvider);
		}

		private void editToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if ( dgridObjectList.SelectedRows.Count < 1 ) return;
			DataRowView drv = dgridObjectList.SelectedRows[0].DataBoundItem as DataRowView;
			IRepositoryItem item = Global.Data.RepositoryService.GetItem((ItemType)drv["type"], (int)drv["id"], false);
			Helpers.OpenDiagram(item, _serviceProvider);
		}

		private void dgridObjectList_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
		{
			if ( e.Button == MouseButtons.Right ) {
				dgridObjectList.CurrentCell = dgridObjectList[e.ColumnIndex, e.RowIndex];
				editToolStripMenuItem.Visible = ItemTypes.HasDiagram((ItemType)dgridObjectList[colType.Index, e.RowIndex].Value);
			}
		}
	}
}
